package com.labot.authentication.providers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;

import com.labot.authentication.ldap.activedirectory.DomainController;
import com.labot.dao.AuditDao;
import com.labot.model.User;
import com.labot.service.UserManager;
import com.labot.types.AuditEventType;
import com.labot.types.AuditType;
import com.labot.types.ConstantsType;
import com.labot.types.LoginType;
import com.labot.webapp.listener.StartupListener;

public class MyAuthenticationProvider extends ShaPasswordEncoder {

	@Autowired
	UserManager userManager;
	
	@Autowired
    DomainController domainController;
	
	@Autowired
	AuditDao audit;
	
	public void setUserManager(UserManager dao) {
		this.userManager = dao;
	}
	
	/**
	 * TODO:
	 * Construir el LDAP
	 */
	@Override
	public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
		if (salt == null) {
			audit.log(AuditEventType.USER_ERROR_LOGIN, AuditType.ERROR, this.getClass().getSimpleName(), null, "ACCESS DENIED. Username is null.");
			return false;
		}
		String username = salt.toString();
		
		User user = (User)userManager.getUserByUsername(username);
		if(user == null){
			audit.log(AuditEventType.USER_ERROR_LOGIN, AuditType.INFO, this.getClass().getSimpleName(), username, "ACCESS DENIED. User not found.");
			return false; //si el usuario es null no debe ingresar.
		}
		if (rawPass != null) {
			if (rawPass.trim().equals("")) {
				audit.log(AuditEventType.USER_ERROR_LOGIN, AuditType.INFO, this.getClass().getSimpleName(), username, "ACCESS DENIED. Password is empty.");
				return false; //NO DEBE POR NINGUN MOTIVO UN USUARIO INGRESAR SIN CLAVE!
			}
		} else {
			return false;
		}
		
		/**
		 * INTERNAL CHECK! using ShaPasswordEncoder
		 */
		if (user.getLoginType().equals(LoginType.INTERNAL)) {			
			Boolean access = super.isPasswordValid(encPass, rawPass, salt);
			if (access) {
				audit.log(AuditEventType.USER_LOGGED_IN, AuditType.INFO, this.getClass().getSimpleName(), username, "ACCESS GRANTED");
			} else {
				audit.log(AuditEventType.USER_ERROR_LOGIN, AuditType.INFO, this.getClass().getSimpleName(), username, "ACCESS DENIED. Wrong password.");
			}
			return access;
			
		/**
		 * LDAP CHECK! using External service DomainController	
		 */
		} else if(user.getLoginType().equals(LoginType.LDAP) && (StartupListener.isEnabledConfig(ConstantsType.LDAP_ENABLED))) { //debe estar ENABLED el LDAP			
			Boolean access = domainController.authenticateUser(username + "@" + StartupListener.getConfigValue(ConstantsType.LDAP_DOMAIN), rawPass);
			if (access) {
				audit.log(AuditEventType.USER_LOGGED_IN, AuditType.INFO, this.getClass().getSimpleName(), username, "ACCESS GRANTED");
			} else {
				audit.log(AuditEventType.USER_ERROR_LOGIN, AuditType.INFO, this.getClass().getSimpleName(), username, "ACCESS DENIED. Wrong password.");
			}
			
			return access; 
		}
		return false; //Si saltea todos los pasos no funciona.		
	}

}
